package com.xgimi.open.skill.datamanager.biz.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.xgimi.open.skill.datamanager.biz.common.Enum.ExceptionErrorCode;
import com.xgimi.open.skill.datamanager.biz.common.exception.BizException;
import com.xgimi.open.skill.datamanager.biz.common.exception.ParamException;
import com.xgimi.open.skill.datamanager.biz.dto.ProductDTO;
import com.xgimi.open.skill.datamanager.biz.service.ProductBizService;
import com.xgimi.open.skill.datamanager.biz.vo.ProductVO;
import com.xgimi.open.skill.datamanager.biz.vo.ProductVersionVO;
import com.xgimi.open.skill.datamanager.domain.entity.ProductDo;
import com.xgimi.open.skill.datamanager.domain.entity.ProductVersionDo;
import com.xgimi.open.skill.datamanager.domain.service.ProductService;
import com.xgimi.open.skill.datamanager.domain.service.ProductVersionService;
import com.xgimi.open.skill.datamanager.service.response.page.IPageUtils;
import com.xgimi.open.skill.datamanager.service.response.page.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author coderzpw.zhang
 * @version 1.0
 * @description 描述
 * @date 2023/2/3 13:42
 */
@Slf4j
@Service
public class ProductBizServiceImpl implements ProductBizService {

    /**
     * 产品版本 发布状态（0：未发布，1：已发布）
     */
    public static final Integer VERSION_PUBLISHED = 1;
    /**
     * 产品 待开发
     */
    public static final Integer TO_BE_DEVELOPED = 0;
    /**
     * 产品 开发中
     */
    public static final Integer DEVELOPING = 1;
    /**
     * 产品 已发布
     */
    public static final Integer PRODUCT_PUBLISHED = 2;


    @Autowired
    private ProductService productService;
    @Autowired
    private ProductVersionService productVersionService;


    @Override
    public Boolean addProduct(ProductVO productVO) {
        ProductDo productDo = new ProductDo();
        BeanUtils.copyProperties(productVO, productDo);
        // 1、查询表中是否已有重复的product，根据productName判断
        if (StringUtils.isEmpty(productDo.getProductName())) {
            return Boolean.FALSE;
        }
        List<ProductDo> list = productService.queryProductByName(productDo);
        if (list.size() > 0) {
            throw new BizException(ExceptionErrorCode.PRODUCT_NAME_ALREADY_EXISTS);
        }
        // 2、新增product
        Boolean ret = productService.saveProduct(productDo);
        return ret;
    }

    @Override
    public PageResult<ProductDTO> pageQuery(ProductVO productVO) {
        // 参数校验
        validPageQuery(productVO);
        // 构造分页查询的入参
        ProductDo productDo = new ProductDo();
        BeanUtils.copyProperties(productVO, productDo);
        IPage<ProductDo> page = new Page<>(productVO.getCurrentPage(), productVO.getPageSize());
        // 调用domain层分页查询的方法
        IPage<ProductDo> iPage = productService.pageQuery(page, productDo);
        // 若查询没结果，则返回空pageResult
        if (CollectionUtils.isEmpty(iPage.getRecords())) {
            log.info("no such product!");
            return new PageResult<>(Lists.newArrayList(), IPageUtils.noDataPaginator(productVO.getPageSize()));
        }
        // 若有结果，则将 DO 转成 DTO
        List<ProductDTO> list = iPage.getRecords().stream().map(d -> {
            ProductDTO dto = new ProductDTO();
            BeanUtils.copyProperties(d, dto);
            return dto;
        }).collect(Collectors.toList());

        return new PageResult<>(list, IPageUtils.transformToPaginator(iPage));
    }

    @Transactional
    @Override
    public Boolean createProductVersion(ProductVersionVO productVersionVO) {
        Long productId = productVersionVO.getProductId();
        if (null == productService.queryById(productId)) {
            throw new BizException(ExceptionErrorCode.PRODUCT_NOT_EXISTS);
        }
        // 1、查询产品版本表中是否已有重复的productVersion，根据productVersionName判断
        ProductVersionDo productVersionDo = new ProductVersionDo();
        BeanUtils.copyProperties(productVersionVO, productVersionDo);
        List<ProductVersionDo> list = productVersionService.queryByPidAndPvName(productVersionDo);
        if (list.size() > 0) {
            throw new BizException(ExceptionErrorCode.P_VERSION_NAME_ALREADY_EXISTS);
        }
        // 2、新增产品版本信息
        Boolean ret = productVersionService.saveProductVersion(productVersionDo);
        // 3.1、先查看产品有多少发布版本和开发版本，来判断是否修改产品状态 （单抽出一个方法，因为删除产品版本也会用到）
        List<ProductVersionDo> productVersionDoList = productVersionService.queryByPid(productId);
        Integer productStatus = judgeProductStatus(productVersionDoList);
        // 3.2、统一进行修改产品表 的 发布状态、技术类型、操作系统等参数信息（根据产品id）
        ProductDo updateProduct = new ProductDo();
        updateProduct.setId(productId);
        updateProduct.setCreationMethod(productVersionVO.getCreationMethod());
        updateProduct.setOperatingSystem(productVersionVO.getOperatingSystem());
        updateProduct.setType(productVersionVO.getType());
        updateProduct.setProductStatus(productStatus);
        productService.updateById(updateProduct);
        return ret;
    }

    /**
     * 判断产品的状态 0：未发布，无版本；1：开发中，有版本，但没有已发布的版本；2：已发布，有已发布的版本
     *
     * @param productVersionDoList
     * @return
     */
    private Integer judgeProductStatus(List<ProductVersionDo> productVersionDoList) {
        if (productVersionDoList.size() < 1) {
            return TO_BE_DEVELOPED;
        }
        boolean isPublishedForProduct = productVersionDoList.stream().anyMatch(item -> {
            return VERSION_PUBLISHED.equals(item.getStatus());
        });
        if (isPublishedForProduct) {
            return PRODUCT_PUBLISHED;
        }
        return DEVELOPING;
    }

    private void validPageQuery(ProductVO vo) {
        if (Objects.isNull(vo.getCurrentPage())) {
            throw new ParamException("[currentPage]不能为空");
        }
        if (Objects.isNull(vo.getPageSize())) {
            throw new ParamException("[pageSize]不能为空");
        }
    }

    @Transactional
    public Boolean testSW(List<ProductDo> productDos) {
        boolean flag = productService.saveBatch(productDos);
        List<ProductDo> collect = productDos.stream().map(x -> {
            System.out.println(x.getId());
            return x;
        }).collect(Collectors.toList());
        return true;
    }
}
